// DriveRoot.h : Declaration of the CDriveRoot

#pragma once
#include "resource.h"       // main symbols
#include "IShellFolderViewCBImpl.h"
#include "AIDPidl.h"
#if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA)
#error "Single-threaded COM objects are not properly supported on Windows CE platform, such as the Windows Mobile platforms that do not include full DCOM support. Define _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA to force ATL to support creating single-thread COM object's and allow use of it's single-threaded COM object implementations. The threading model in your rgs file was set to 'Free' as that is the only threading model supported in non DCOM Windows CE platforms."
#endif



// CDriveRoot

class ATL_NO_VTABLE CDriveRoot :
	public CComObjectRootEx<CComSingleThreadModel>,
	public CComCoClass<CDriveRoot, &CLSID_DriveRoot>,
#ifdef AID_WINVER_WIN_XP // we need to separate these two
	public IShellFolder,
	public IPersistFolder,
#endif
#ifdef AID_WINVER_WIN_VISTA
	public IShellFolder2,
	public IPersistFolder3,
#endif
	public IShellFolderViewCBImpl<CDriveRoot>
{
public:
	CDriveRoot()
	{
	}

	BEGIN_COM_MAP(CDriveRoot)
		COM_INTERFACE_ENTRY(IShellFolder)		
		COM_INTERFACE_ENTRY(IShellFolder2)
      	COM_INTERFACE_ENTRY2(IPersist, IPersistFolder)
      	COM_INTERFACE_ENTRY(IPersistFolder)
      	COM_INTERFACE_ENTRY(IPersistFolder2)
      	COM_INTERFACE_ENTRY(IPersistFolder3)
	END_COM_MAP()

   BEGIN_MSG_MAP(CDriveRoot)
      MESSAGE_HANDLER(SFVM_WINDOWCREATED, OnWindowCreated)
      //MESSAGE_HANDLER(SFVM_LISTREFRESHED, OnListRefreshed)
      MESSAGE_HANDLER(SFVM_GETNOTIFY, OnGetNotify)
   END_MSG_MAP()


DECLARE_PROTECT_FINAL_CONSTRUCT()
   
	//registration 
	static HRESULT WINAPI UpdateRegistry(BOOL bRegister) throw();
	
	HRESULT		FinalConstruct();
	void FinalRelease();

	//implemented interfaces
public:
	//IShellFolder
	STDMETHOD(ParseDisplayName)(HWND hwnd, IBindCtx* pbc, PWSTR pszDisplayName, ULONG* pchEaten, PIDLIST_RELATIVE* ppidl, ULONG* pdwAttributes);
	STDMETHOD(EnumObjects)(HWND hwnd, SHCONTF grfFlags, IEnumIDList** ppEnumIDList);
	STDMETHOD(BindToObject)(PCUIDLIST_RELATIVE pidl, IBindCtx* pbc, REFIID riid, LPVOID* ppRetVal);
	STDMETHOD(BindToStorage)(PCUIDLIST_RELATIVE pidl, IBindCtx* pbc, REFIID riid, LPVOID* ppRetVal);
	STDMETHOD(CompareIDs)(LPARAM lParam, PCUIDLIST_RELATIVE pidl1, PCUIDLIST_RELATIVE pidl2);
	STDMETHOD(CreateViewObject)(HWND hwndOwner, REFIID riid, LPVOID* ppRetVal);
	STDMETHOD(GetAttributesOf)(UINT cidl, PCUITEMID_CHILD_ARRAY rgpidl, SFGAOF* rgfInOut);
	STDMETHOD(GetUIObjectOf)(HWND hwndOwner, UINT cidl, PCUITEMID_CHILD_ARRAY rgpidl, REFIID riid, UINT* rgfReserved, LPVOID* ppRetVal);
	STDMETHOD(GetDisplayNameOf)(PCUITEMID_CHILD pidl, SHGDNF uFlags, STRRET* psrName);
	STDMETHOD(SetNameOf)(HWND hwnd, PCUITEMID_CHILD pidl, LPCWSTR pszName, SHGDNF uFlags, PITEMID_CHILD* ppidlOut);
   
	// IShellFolder2
#ifdef AID_WINVER_WIN_VISTA
   STDMETHOD(GetDefaultSearchGUID)(GUID* pguid);
   STDMETHOD(EnumSearches)(IEnumExtraSearch** ppenum);
   STDMETHOD(GetDefaultColumn)(DWORD dwRes, ULONG* pSort, ULONG* pDisplay);
   STDMETHOD(GetDefaultColumnState)(UINT iColumn, SHCOLSTATEF* pcsFlags);
   STDMETHOD(GetDetailsEx)(PCUITEMID_CHILD pidl, const SHCOLUMNID* pscid, VARIANT* pv);
   STDMETHOD(GetDetailsOf)(PCUITEMID_CHILD pidl, UINT iColumn, SHELLDETAILS* psd);
   STDMETHOD(MapColumnToSCID)(UINT iColumn, SHCOLUMNID* pscid);
#endif
	// IShellFolderViewCB messages
	LRESULT OnWindowCreated(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
   	LRESULT OnGetNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
   	//LRESULT OnListRefreshed(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);

	// IPersist
	STDMETHOD(GetClassID)(CLSID* pclsid);
	
	// IPersistFolder
	STDMETHOD(Initialize)(PCIDLIST_ABSOLUTE pidl);
	
	// IPersistFolder2
	STDMETHOD(GetCurFolder)(PIDLIST_ABSOLUTE* ppidl);
	
	// IPersistFolder3
	STDMETHOD(InitializeEx)(IBindCtx* pbc, PCIDLIST_ABSOLUTE pidlRoot, const PERSIST_FOLDER_TARGET_INFO* pPFTI);
	STDMETHOD(GetFolderTargetInfo)(PERSIST_FOLDER_TARGET_INFO* pPFTI);
	
private:
	AIDPidl		m_root;
	AIDPidl		m_crtFolder;
};

OBJECT_ENTRY_AUTO(CLSID_DriveRoot, CDriveRoot)
